1   /*
2    * Copyright (c) 2004-2005, University Health Network.  All rights reserved. Distributed under the BSD 
3    * license (see http://opensource.org/licenses/bsd-license.php).
4    *  
5    * ChunkBasedSemanticCache.java
6    *
7    * Created on 10-Dec-2004 at 10:58:22 AM
8    */
9   package ca.uhn.cache.impl;
10  
11  import java.util.Date;
12  
13  import junitx.framework.ArrayAssert;
14  
15  import org.jmock.Mock;
16  import org.jmock.MockObjectTestCase;
17  
18  import ca.uhn.cache.CacheReasonEnum;
19  import ca.uhn.cache.IDimension;
20  import ca.uhn.cache.IParamSpace;
21  import ca.uhn.cache.IQuery;
22  import ca.uhn.cache.IQueryParam;
23  import ca.uhn.cache.VolatilityEnum;
24  import ca.uhn.cache.exception.CacheException;
25  import ca.uhn.cache.internal.IChunk;
26  import ca.uhn.cache.internal.IChunkStore;
27  
28  
29  /***
30   * Tests for cache accepting queries spanning 1 dimension.
31   * 
32   * Fixture description:
33   * 
34   * dimension1:StringSetParam = P( { A, B, C ,D, E } ), where P is the "power set".
35   * 
36   * chunk1 = { A, B }
37   * 
38   * chunk2 = { C, D, E }
39   * 
40   * @author <a href="mailto:alexei.guevara@uhn.on.ca">Alexei Guevara</a>
41   * @version $Revision: 1.2 $ updated on $Date: 2005/01/25 22:04:24 $ by $Author: aguevara $
42   */
43  public class ChunkBasedSemanticCacheTest1 extends MockObjectTestCase {
44      
45      private ChunkBasedSemanticCache myChunkBasedSemanticCache;
46      
47      private Mock myParamSpaceMock;
48      private IParamSpace myParamSpace;
49      
50      private Mock myChunkStoreMock;
51      private IChunkStore myChunkStore;
52      
53      private IDimension myDimension1;
54  
55      private IChunk myChunk1;
56      private IChunk myChunk2;
57      
58      private IQuery myChunk1Query;    
59      private IQuery myChunk2Query;
60  
61      private StringSetParam myChunk2QueryParam1;
62  
63      private StringSetParam myChunk1QueryParam1;
64      
65  
66      /*
67       * @see TestCase#setUp()
68       */
69      protected void setUp() throws Exception {
70          super.setUp();
71          
72          myChunkBasedSemanticCache = new ChunkBasedSemanticCache();
73          
74          myParamSpaceMock = new Mock( IParamSpace.class, "myParamSpace" );
75          myParamSpace = (IParamSpace) myParamSpaceMock.proxy();
76          
77          myChunkStoreMock = new Mock( IChunkStore.class, "myChunkStore" );
78          myChunkStore = (IChunkStore) myChunkStoreMock.proxy();
79          
80          myChunkBasedSemanticCache.setParamSpace( myParamSpace );
81          myChunkBasedSemanticCache.setChunkStore( myChunkStore );
82          
83          myDimension1 = new Dimension( "P( A, B, C, D, E )", new Class[] { StringSetParam.class } );
84          
85          myChunk1QueryParam1 = new StringSetParam( myDimension1, new String[] { "A", "B" } );
86          myChunk1Query = new Query();
87          myChunk1Query.addParameter( myChunk1QueryParam1 );
88          myChunk1 = 
89              new Chunk( "chunkId1", VolatilityEnum.STABLE, 
90                         new Date(), new Date(1000000), new Date(), 
91                         new CacheReasonEnum[] { CacheReasonEnum.PRE_FETCH }, 
92                         myChunk1Query );
93          
94          myChunk2QueryParam1 = new StringSetParam( myDimension1, new String[] { "C", "D", "E" } );
95          myChunk2Query = new Query();
96          myChunk2Query.addParameter( myChunk2QueryParam1 );
97          myChunk2 = 
98              new Chunk( "chunkId2", VolatilityEnum.STABLE, 
99                         new Date(), new Date(1000001), new Date(), 
100                        new CacheReasonEnum[] { CacheReasonEnum.PRE_FETCH }, 
101                        myChunk2Query );
102         
103     }
104 
105     /*
106      * @see TestCase#tearDown()
107      */
108     protected void tearDown() throws Exception {
109         super.tearDown();
110     }
111 
112     /***
113      * @throws CacheException ...
114      */
115     public void testRemainder1_1() throws CacheException {
116         
117         IQuery query = new Query();
118         
119         IQuery[] expectedReminder = new IQuery[] {};
120         
121         IQuery[] actualRemider = myChunkBasedSemanticCache.remainder( query , 0 );
122         
123         ArrayAssert.assertEquals( expectedReminder, actualRemider );
124     }
125     
126     /***
127      * - empty chunk store
128      * 
129      * @throws CacheException ...
130      */
131     public void testRemainder2_1() throws CacheException {
132         //empty chunk store
133         myChunkStoreMock
134             .expects( once() ).method( "get" ).with( eq( myChunk1Query ) ).will( returnValue( null ) );
135 
136         //original query (spans chunk 1)
137         StringSetParam queryParam = new StringSetParam( myDimension1, new String[] { "A" } );        
138         IQuery query = new Query();
139         query.addParameter( queryParam );
140         
141         //param within chunk1
142         myParamSpaceMock.expects( once() )
143             .method( "chunk" )
144             .with( eq( queryParam ) ) 
145             .will( returnValue( new IQueryParam[] { myChunk1QueryParam1 } ) );
146         
147         //expected remider query
148         IQuery[] expectedReminder = new IQuery[] { myChunk1Query };
149         
150         //actual query
151         IQuery[] actualRemider = myChunkBasedSemanticCache.remainder( query , 0 );
152         
153         ArrayAssert.assertEquals( expectedReminder, actualRemider );
154     }
155     
156     /***
157      * - empty chunk store
158      * 
159      * @throws CacheException ...
160      */
161     public void testRemainder2_2() throws CacheException {
162         //empty chunk store
163         myChunkStoreMock
164             .expects( once() ).method( "get" ).with( eq( myChunk2Query ) ).will( returnValue( null ) );
165         
166         //original query (spans chunk 2)
167         StringSetParam queryParam = new StringSetParam( myDimension1, new String[] { "D" } );        
168         IQuery query = new Query();
169         query.addParameter( queryParam );
170         
171         //param within chunk2
172         myParamSpaceMock.expects( once() )
173             .method( "chunk" )
174             .with( eq( queryParam ) )
175             .will( returnValue( new IQueryParam[] { myChunk2QueryParam1 } ) );
176         
177         IQuery[] expectedReminder = new IQuery[] { myChunk2Query };
178         
179         //actual query
180         IQuery[] actualRemider = myChunkBasedSemanticCache.remainder( query , 0 );
181         
182         ArrayAssert.assertEquals( expectedReminder, actualRemider );
183     }
184 
185     /***
186      * - empty chunk store
187      * 
188      * @throws CacheException ...
189      */
190     public void testRemainder2_3() throws CacheException {
191         //empty chunk store
192         myChunkStoreMock
193             .expects( once() ).method( "get" ).with( eq( myChunk1Query ) ).will( returnValue( null ) );
194         myChunkStoreMock
195             .expects( once() ).method( "get" ).with( eq( myChunk2Query ) ).will( returnValue( null ) );
196         
197         //original query (spans chunk 1 and 2)
198         StringSetParam queryParam = new StringSetParam( myDimension1, new String[] { "A", "D" } );
199         IQuery query = new Query();
200         query.addParameter( queryParam );
201         
202         //param within chunk1 and chunk2
203         myParamSpaceMock.expects( once() )
204             .method( "chunk" )
205             .with( eq( queryParam ) ) 
206             .will( returnValue( new IQueryParam[] { myChunk1QueryParam1, myChunk2QueryParam1 } ) );
207         
208         IQuery[] expectedReminder = new IQuery[] { myChunk1Query, myChunk2Query };
209         
210         //actual query
211         IQuery[] actualRemider = myChunkBasedSemanticCache.remainder( query , 0 );
212         
213         ArrayAssert.assertEquals( expectedReminder, actualRemider );
214     }
215     
216     /***
217      * - chunk1 in chunk store
218      * 
219      * @throws CacheException ...
220      */
221     public void testRemainder3_1() throws CacheException {
222         //empty chunk store
223         myChunkStoreMock
224             .expects( once() ).method( "get" ).with( eq( myChunk1Query ) ).will( returnValue( myChunk1 ) );
225 
226         //original query (spans chunk 1)
227         StringSetParam queryParam = new StringSetParam( myDimension1, new String[] { "A" } );        
228         IQuery query = new Query();
229         query.addParameter( queryParam );
230         
231         //param within chunk1
232         myParamSpaceMock.expects( once() )
233             .method( "chunk" )
234             .with( eq( queryParam ) ) 
235             .will( returnValue( new IQueryParam[] { myChunk1QueryParam1 } ) );
236         
237         //expected remider query
238         IQuery[] expectedReminder = new IQuery[] {};
239         
240         //actual query
241         IQuery[] actualRemider = myChunkBasedSemanticCache.remainder( query , 0 );
242         
243         ArrayAssert.assertEquals( expectedReminder, actualRemider );
244     }
245     
246     /***
247      * - chunk2 in chunk store
248      * 
249      * @throws CacheException ...
250      */
251     public void testRemainder3_2() throws CacheException {
252         //empty chunk store
253         myChunkStoreMock
254             .expects( once() ).method( "get" ).with( eq( myChunk2Query ) ).will( returnValue( myChunk2 ) );
255         
256         //original query (spans chunk 2)
257         StringSetParam queryParam = new StringSetParam( myDimension1, new String[] { "D" } );        
258         IQuery query = new Query();
259         query.addParameter( queryParam );
260         
261         //param within chunk2
262         myParamSpaceMock.expects( once() )
263             .method( "chunk" )
264             .with( eq( queryParam ) )
265             .will( returnValue( new IQueryParam[] { myChunk2QueryParam1 } ) );
266         
267         IQuery[] expectedReminder = new IQuery[] {};
268         
269         //actual query
270         IQuery[] actualRemider = myChunkBasedSemanticCache.remainder( query , 0 );
271         
272         ArrayAssert.assertEquals( expectedReminder, actualRemider );
273     }
274 
275     /***
276      * - chunk1 in chunk store
277      * 
278      * @throws CacheException ...
279      */
280     public void testRemainder3_3() throws CacheException {
281         //empty chunk store
282         myChunkStoreMock
283             .expects( once() ).method( "get" ).with( eq( myChunk1Query ) ).will( returnValue( myChunk1 ) );
284         myChunkStoreMock
285             .expects( once() ).method( "get" ).with( eq( myChunk2Query ) ).will( returnValue( null ) );
286         
287         //original query (spans chunk 1 and 2)
288         StringSetParam queryParam = new StringSetParam( myDimension1, new String[] { "A", "D" } );
289         IQuery query = new Query();
290         query.addParameter( queryParam );
291         
292         //param within chunk1 and chunk2
293         myParamSpaceMock.expects( once() )
294             .method( "chunk" )
295             .with( eq( queryParam ) ) 
296             .will( returnValue( new IQueryParam[] { myChunk1QueryParam1, myChunk2QueryParam1 } ) );
297         
298         IQuery[] expectedReminder = new IQuery[] { myChunk2Query };
299         
300         //actual query
301         IQuery[] actualRemider = myChunkBasedSemanticCache.remainder( query , 0 );
302         
303         ArrayAssert.assertEquals( expectedReminder, actualRemider );
304     }
305     
306     /***
307      * - chunk2 in chunk store
308      * 
309      * @throws CacheException ...
310      */
311     public void testRemainder3_4() throws CacheException {
312         //empty chunk store
313         myChunkStoreMock
314             .expects( once() ).method( "get" ).with( eq( myChunk1Query ) ).will( returnValue( null ) );
315         myChunkStoreMock
316             .expects( once() ).method( "get" ).with( eq( myChunk2Query ) ).will( returnValue( myChunk2 ) );
317         
318         //original query (spans chunk 1 and 2)
319         StringSetParam queryParam = new StringSetParam( myDimension1, new String[] { "A", "D" } );
320         IQuery query = new Query();
321         query.addParameter( queryParam );
322         
323         //param within chunk1 and chunk2
324         myParamSpaceMock.expects( once() )
325             .method( "chunk" )
326             .with( eq( queryParam ) ) 
327             .will( returnValue( new IQueryParam[] { myChunk1QueryParam1, myChunk2QueryParam1 } ) );
328         
329         IQuery[] expectedReminder = new IQuery[] { myChunk1Query };
330         
331         //actual query
332         IQuery[] actualRemider = myChunkBasedSemanticCache.remainder( query , 0 );
333         
334         ArrayAssert.assertEquals( expectedReminder, actualRemider );
335     }
336 
337     /***
338      * - chunk1 and chunk2 in chunk store
339      * 
340      * @throws CacheException ...
341      */
342     public void testRemainder3_5() throws CacheException {
343         //empty chunk store
344         myChunkStoreMock
345             .expects( once() ).method( "get" ).with( eq( myChunk1Query ) ).will( returnValue( myChunk1 ) );
346         myChunkStoreMock
347             .expects( once() ).method( "get" ).with( eq( myChunk2Query ) ).will( returnValue( myChunk2 ) );
348         
349         //original query (spans chunk 1 and 2)
350         StringSetParam queryParam = new StringSetParam( myDimension1, new String[] { "A", "D" } );
351         IQuery query = new Query();
352         query.addParameter( queryParam );
353         
354         //param within chunk1 and chunk2
355         myParamSpaceMock.expects( once() )
356             .method( "chunk" )
357             .with( eq( queryParam ) ) 
358             .will( returnValue( new IQueryParam[] { myChunk1QueryParam1, myChunk2QueryParam1 } ) );
359         
360         IQuery[] expectedReminder = new IQuery[] {};
361         
362         //actual query
363         IQuery[] actualRemider = myChunkBasedSemanticCache.remainder( query , 0 );
364         
365         ArrayAssert.assertEquals( expectedReminder, actualRemider );
366     }
367     
368     /***
369      * @throws Exception ...
370      */
371     public void testGetEarliestCacheTime() throws Exception {
372         IQueryParam q1 = myChunk1.getBoundaries().getParamByDimension(myDimension1);
373         IQueryParam q2 = myChunk2.getBoundaries().getParamByDimension(myDimension1);
374         
375         IQueryParam param = new StringSetParam(myDimension1, new String[] {"B", "C"});
376         IQuery query = new Query();
377         query.addParameter(param);
378 
379         myParamSpaceMock.expects( once() ).method("chunk").with( eq(param) )
380             .will( returnValue( new IQueryParam[] {q1, q2}) );
381         
382         myChunkStoreMock.expects( atLeastOnce() ).method("get")
383             .will( onConsecutiveCalls(returnValue(myChunk1), returnValue(myChunk2)) );
384         
385         Date earliest = myChunkBasedSemanticCache.getEarliestCacheTime(query);
386         
387         assertEquals(1000000, earliest.getTime());
388     }
389     
390 }
391